package com.nari.kmd_dataservice.util;

import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

/**
 * @ClassName: HttpClientUtils
 * @Description: 生成RestTemplate的模板，具体内容如下：其中设置了信任所有的证书，并且不会对域名进行检查之类的开放性措施
 * @Author: zhangnaijiang
 * @Date: 2022/01/22 14:43
 * @Version 1.0.0
 */
public class HttpClientUtils {

    public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        HttpClientBuilder b = HttpClientBuilder.create();

        if(b!=null){
            // setup a Trust Strategy that allows all certificates.
            SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
            if(sslContextBuilder!=null){
                SSLContextBuilder load = sslContextBuilder.loadTrustMaterial(null, new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                        return true;
                    }
                });
                if(load!=null){
                    SSLContext sslContext = load.build();
                    b.setSSLContext(sslContext);

                    // don't check Hostnames, either.
                    //      -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
                    HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;

                    // here's the special part:
                    //      -- need to create an SSL Socket Factory, to use our weakened "trust strategy";
                    //      -- and create a Registry, to register it.
                    //
                    SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
                    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                            .register("http", PlainConnectionSocketFactory.getSocketFactory())
                            .register("https", sslSocketFactory)
                            .build();

                    // now, we create connection-manager using our Registry.
                    //      -- allows multi-threaded use
                    PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
                    connMgr.setMaxTotal(200);
                    connMgr.setDefaultMaxPerRoute(100);
                    b.setConnectionManager( connMgr);

                    // finally, build the HttpClient;
                    //      -- done!
                    CloseableHttpClient client = b.build();

                    return client;
                }
            }
        }
        return null;
    }

}